Skip to content

webpack 配置文件(webpack.config.js) ​

Webpack 的配置文件是一个 Node.js 模块,它导出一个对象。这个对象告诉 Webpack 如何处理你的项目,从哪里开始、如何处理不同类型的文件、以及最终输出到哪里。

核心模块 ​

shell
入口 (Entry)
输出 (Output)
模块 (Module)
插件 (Plugins)
模式 (Mode)
解析 (Resolve)
开发工具 (Devtool)
开发服务器 (DevServer) (用于开发环境)
优化 (Optimization)

配置选项 ​

1、入口 (Entry) ​

entry 用来指定 Webpack 打包的起始文件。Webpack 会从这个文件开始,递归地查找所有依赖的模块。

shell
# 单入口
module.exports = {
  entry: './src/index.js'
};

# 多入口
module.exports = {
  entry: {
    app: './src/app.js',
    vendor: './src/vendor.js'
  }
};

2、输出 (Output) ​

output 配置项用来告诉 Webpack 打包后的文件应该输出到哪里,以及如何命名。

js
const path = require('path'); // Node.js 的 path 模块

module.exports = {
  // ...
  output: {
    filename: 'bundle.js', // 单入口时的文件名
    // 多入口时,可以使用占位符 [name]
    // filename: '[name].[contenthash].js', // [name] 会被替换为 entry 的键名, [contenthash] 是文件内容的哈希值,用于缓存控制
    path: path.resolve(__dirname, 'dist'), // 将打包后的文件输出到项目根目录下的 dist 文件夹
  },
};

3、模块 (Module) ​

Webpack 本身只能处理 JavaScript 和 JSON 文件。对于其他类型的文件(如 CSS, 图片,TypeScript 等),我们需要使用 Loader 来将它们转换为 Webpack 可以处理的模块。

js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i, // 匹配所有 .css 结尾的文件
        use: ['style-loader', 'css-loader'], // 自右向左执行:先 css-loader 再 style-loader,最终注入页面
        // 执行顺序(链上):css-loader → style-loader
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i, // 匹配图片文件
        type: 'asset/resource', // Webpack 5 新增的 Asset Modules,替代了 file-loader
        // 会将文件输出到 output.path 目录,并返回一个 URL。
      },
      {
        test: /\.m?js$/, // 匹配 JS 文件
        exclude: /node_modules/, // 排除 node_modules 目录
        use: {
          loader: 'babel-loader', // 使用 babel-loader 转译 JS,通常配合 @babel/preset-env 的 targets 指定语法目标
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
};

4、插件 (Plugins) ​

Loader 用于转换特定类型的文件,而 Plugin 则可以执行更广泛的任务,比如:打包优化、资源管理、注入环境变量、生成 HTML 文件等。

js
const HtmlWebpackPlugin = require('html-webpack-plugin'); // 生成 HTML 文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 将 CSS 提取到单独的文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 亦可使用 output.clean: true(Webpack 5 内置)替代

module.exports = {
  // ...
  plugins: [
    new CleanWebpackPlugin(), // 在每次构建前清理 dist 文件夹
    new HtmlWebpackPlugin({
      template: './src/index.html', // 使用模板
      title: 'My App',
      minify: {
        // 压缩 HTML
        removeComments: true,
        collapseWhitespace: true,
      },
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css', // 提取后的 CSS 文件名
    }),
  ],
};

5、模式 (Mode) ​

mode 配置项可以启用 Webpack 内置的优化,它有三个可选值:development、production 或 none。

js
module.exports = {
  mode: 'development',
};

6、解析 (Resolve) ​

resolve 配置项用于设置模块如何被解析,比如如何查找模块文件、文件后缀名等。

js
const path = require('path');

module.exports = {
  // ...
  resolve: {
    extensions: ['.js', '.json', '.jsx', '.css'], // 尝试按这些后缀名查找文件
    alias: {
      '@': path.resolve(__dirname, 'src/'), // 将 @ 指向 src 目录
      components: path.resolve(__dirname, 'src/components/'),
    },
  },
};
// 使用时:import Header from '@/components/Header';

7、开发工具 (Devtool) ​

devtool 控制 Source Map 的生成方式与精度,便于调试;不同取值在「构建速度 / 产物体积 / 映射准确度」之间权衡。常用:eval-cheap-module-source-map(开发)、source-map(需完整映射时)、生产环境常关闭或仅用隐藏 Source Map。

js
module.exports = {
  devtool: 'eval-cheap-module-source-map',
};

8、开发服务器 (DevServer) ​

webpack-dev-server 是一个用于开发的小型 HTTP 服务器,它提供了实时重新加载(live reloading) 和 热模块替换(Hot Module Replacement, HMR) 功能。

js
module.exports = {
  // ...
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'), // Webpack 5 中 contentBase 被 static 取代
    },
    port: 9000,
    open: true,
    hot: true,
    compress: true,
    proxy: {
      '/api': {
        target: 'http://localhost:3000', // 后端 API 服务器地址
        pathRewrite: { '^/api': '' }, // 重写路径
      },
    },
  },
};

9、优化 (Optimization) ​

optimization 配置项用于自定义 Webpack 的优化策略。

js
module.exports = {
  // ...
  optimization: {
    splitChunks: {
      chunks: 'all', // 对所有类型的 chunks 进行分割(包括异步和同步)
      cacheGroups: {
        vendor: {
          // 提取第三方库
          test: /[\\/]node_modules[\\/]/,
          name: 'vendors',
          chunks: 'all',
        },
      },
    },
  },
};

webpack 常见配置 ​

js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    filename: '[name].[contenthash].js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/', // 配置公共路径,用于CDN或本地开发
  },
  devtool: 'eval-cheap-module-source-map',
  devServer: {
    static: {
      directory: path.join(__dirname, 'dist'),
    },
    port: 8080,
    open: true,
    hot: true,
    historyApiFallback: true, // 用于单页应用路由
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      {
        test: /\.css$/,
        use: [
          process.env.NODE_ENV === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
        ],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
    ],
  },
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
    }),
  ],
  resolve: {
    extensions: ['.js', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src/'),
    },
  },
  optimization: {
    splitChunks: {
      chunks: 'all',
    },
  },
};